import json
import requests
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler

from jindie.jd_crawler import JDCrawler
from redis_manage import RedisManager
from settings import *
from logging_config import get_device_logger

# API_HOST = 'http://localhost:8000'
API_HOST = 'http://app.iqnn.com.cn/rt'

logger = get_device_logger("jd_task")


class JDCrawlerTask:
    def __init__(self):
        self.scheduler = None
        self.redis_client = RedisManager().get_client()
        self.REDIS_KEY = "jd_task_ids:{}"
        self.status_check_job = None
        self.cookies = self.get_cookie()
        self.crawler = JDCrawler(cookies=self.cookies)
        st_data = self.crawler.crawl_staff_data()
        self.user_phone = None
        if st_data and st_data.get("code") == 200:
            self.user_phone = st_data.get("data").get('ULOGIN')
            self.REDIS_KEY = self.REDIS_KEY.format(self.user_phone)
            pass

    def get_cookie(self):
        jd_cookie_path = "c:\\jd_cookie.txt"
        cookies = ""
        try:
            with open(jd_cookie_path, 'r', encoding='utf-8') as f:
                cookies = f.read().strip()
                logger.info(f"Cookie文件已找到: {jd_cookie_path},{cookies}")
        except FileNotFoundError:
            logger.warning(f"Cookie文件未找到: {jd_cookie_path}，使用默认cookie")
            cookies = "PHPSESSID=4dknpgjncakem0sskt7vd8vumm;"
        except Exception as e:
            logger.error(f"读取cookie文件失败: {e}，使用默认cookie")
            cookies = "PHPSESSID=4dknpgjncakem0sskt7vd8vumm;"

        logger.info(f"==============Cookie: {cookies}============")
        return cookies

    def run_task(self):
        """运行爬虫任务"""
        customers = self.crawler.get_customers()
        # logger.info(f"构建客户数据{customers}")
        task_str = self.redis_client.get(self.REDIS_KEY)
        # 有客户列表，且没任务，创建任务
        if customers and not task_str:
            logger.info(f"[创建任务] 开始创建轮呼任务")
            ret = self.create_call_task(customers)
            if ret.get('code') == 200:
                task_ids = ret.get('data')
                logger.info(f"[创建任务] 轮呼任务成功，任务id{task_ids}")
                self.redis_client.set(self.REDIS_KEY, json.dumps(task_ids))
                self.update_task_interval(30)
                # 开启任务状态监控
                self.start_status_monitor()

        elif  customers and task_str:
            # 如果没开，开启监控
            self.start_status_monitor()
            logger.info(f"[任务进行中]，{task_str},{len(customers)} 任务进行中...")
            pass
        elif not customers and task_str:
            tasks = json.loads(task_str)
            for task_id in tasks:
                logger.info(f"[jd取消任务]，{task_id}停止...")
                self.stop_call_task(task_id)
                #  删除任务列表
                self.redis_client.delete(self.REDIS_KEY)
                if self.status_check_job:
                    self.status_check_job.remove()
                    self.status_check_job = None
                    logger.info("[jd取消任务],任务状态监控已停止")

                # 更新任务执行间隔
                self.update_task_interval(15)
        else:
            logger.info(f"=====  jd无轮呼任务 =====")
    def create_call_task(self, customers):
        api_url = API_HOST + "/customers/task-run"
        data = {
            "customers": customers,
            "channel":self.user_phone
        }
        ret = requests.post(api_url, json=data)

        logger.info(f"调用接口返回结果{ret.json()}")
        return ret.json()

    def stop_call_task(self, task_id):
        api_url = API_HOST + f"/call/tasks/{task_id}/stop"
        data = {}
        ret = requests.post(api_url, json=data)

        logger.info(f"调用接口返回结果{ret.json()}")
        return ret.json()

    def update_task_interval(self, seconds):
        """更新定时任务执行间隔"""
        if self.scheduler and hasattr(self.scheduler, 'get_jobs'):
            jobs = self.scheduler.get_jobs()
            for job in jobs:
                # 移除旧任务
                self.scheduler.remove_job(job.id)
            # 添加新任务，使用新的时间间隔
            self.scheduler.add_job(self.run_task, 'interval', seconds=seconds)
            logger.info(f"定时任务间隔已更新为{seconds}秒")

    def start_background(self):
        """以后台方式启动定时任务"""
        self.scheduler = BackgroundScheduler()
        # 添加任务，每5秒执行一次
        self.scheduler.add_job(self.run_task, 'interval', seconds=5)
        self.scheduler.start()
        logger.info("京东爬虫后台定时任务已启动，每5秒执行一次")

    def start_status_monitor(self):
        """启动任务状态监控"""
        if self.scheduler and not self.status_check_job:
            logger.info('===== 开启任务状态监控 =====')
            self.status_check_job = self.scheduler.add_job(
                self.check_task_status, 'interval', seconds=30
            )
            logger.info("任务状态监控已启动，每30秒检查一次")

    def start_blocking(self, secs=15):
        if self.user_phone:
            """以阻塞方式启动定时任务"""
            self.scheduler = BlockingScheduler()
            # 添加任务，每5秒执行一次
            self.scheduler.add_job(self.run_task, 'interval', seconds=secs)
            logger.info(f"jd定时任务已启动，每{secs}秒执行一次")
            try:
                self.scheduler.start()
            except KeyboardInterrupt:
                logger.info("收到停止信号，正在关闭定时任务...")
                self.scheduler.shutdown()
                logger.info("定时任务已关闭")
        else:
            logger.error("用户信息获取失败，请检查cookies是否正确")

    def check_task_status(self):
        """
        检查任务状态，轮询任务是否完成
        """
        # 从Redis获取当前任务ID列表
        task_str = self.redis_client.get(self.REDIS_KEY)
        if not task_str:
            logger.info("没有正在进行的任务，跳过状态检查")
            return
        try:
            task_ids = json.loads(task_str)
            # 检查每个任务的状态
            for task_id in task_ids:
                status = self.get_task_status(task_id)
                logger.info(f"[监控任务] {task_id} 状态为 {status}")
                if status == "completed" or status == "cancelled":
                    logger.info(f"[监控任务] {task_id} 已完成,清除jd轮呼列表，清除redis")
                    self.crawler.clear_all_lunhu_tasks()
                    self.redis_client.delete(self.REDIS_KEY)

                    if self.status_check_job:
                        self.status_check_job.remove()
                        self.status_check_job = None
                        logger.info("[监控任务]任务状态监控已停止")

        except json.JSONDecodeError as e:
            logger.exception(f"任务ID解析错误: {e}")
        except Exception as e:
            logger.exception(f"检查任务状态时发生错误: {e}")

    def get_task_status(self, task_id):
        try:
            status_url = f"{API_HOST}/call/tasks/{task_id}/customers"
            response = requests.get(status_url, timeout=10)

            if response.status_code == 200:
                result = response.json()
                return result.get('data').get('task_info').get("status", "")  # 假设返回格式包含status字段
            else:
                logger.error(f"获取任务 {task_id} 状态失败，状态码: {response.status_code}")
                return response.json()

        except requests.exceptions.RequestException as e:
            logger.exception(f"获取任务 {task_id} 状态时网络异常: {e}")
            return "unknown"


# 全局任务实例
jd_task = None

def start_background_task():
    """启动后台定时任务"""
    global jd_task
    if jd_task is None:
        jd_task = JDCrawlerTask()
    jd_task.start_background()
    return jd_task

def shutdown_task():
    """关闭定时任务"""
    global jd_task
    if jd_task and jd_task.scheduler:
        jd_task.scheduler.shutdown()
        jd_task = None
        logger.info("定时任务已关闭")

def main_task():
    # 以阻塞方式运行定时任务
    task = JDCrawlerTask()
    task.start_blocking()

if __name__ == '__main__':
    main_task()